package com.tools.common.container;

import com.fasterxml.jackson.databind.JsonNode;
import com.tools.common.object.C;
import com.tools.common.object.json.JsonKit;
import com.tools.common.object.Note;
import com.tools.common.object.ObjKit;
import com.tools.common.object.string.VerifyKit;

import java.util.*;

/**
 * 在一般的容器中，key 为 String 类型
 * value 为 Object 类型的形式是用的最多的
 * 所以这里默认提供了一个实现
 * */
@Note("在一般的容器中，key 为 String 类型，value 为 Object 类型的形式" +
        "是用的最多的，所以这里默认提供了一个实现")
public class OwnPair extends AbsOwnPair<String, Object> {

    public OwnPair() {
        super(true);
    }

    public OwnPair(int initSize) {
        super(true, initSize);
    }

    public OwnPair(Map map) {
        super(true, (map == null ? 0 : map.size()));
        this.putAll(map);
    }

    public OwnPair(OwnPairs pair) {
        super(true, (pair == null ? 0 : pair.size()));
        this.putAll(pair);
    }

    public OwnPair(MapEnum implEnum) {
        super(true, implEnum);
    }

    public OwnPair(MapEnum implEnum, int initSize) {
        super(true, implEnum, initSize);
    }

    public OwnPair(MapEnum implEnum, int initSize, Comparator<? super String> c) {
        super(true, implEnum, initSize, c);
    }

    public OwnPair(MapEnum implEnum, Comparator<? super String> c) {
        super(true, implEnum, c);
    }

    public OwnPair(MapEnum implEnum, Map map) {
        super(true, implEnum, (map == null ? 0 : map.size()));
        this.putAll(map);
    }

    public OwnPair(MapEnum implEnum, Map map, Comparator<? super String> c) {
        super(true, implEnum, (map == null ? 0 : map.size()), c);
        this.putAll(map);
    }

    public OwnPair(MapEnum implEnum, OwnPairs pair) {
        super(true, implEnum, (pair == null ? 0 : pair.size()));
        this.putAll(pair);
    }

    public OwnPair(MapEnum implEnum, OwnPairs pair, Comparator<? super String> c) {
        super(true, implEnum, (pair == null ? 0 : pair.size()), c);
        this.putAll(pair);
    }

    /* *******************************************************************************************
     *
     *          重写方法
     *
     * *******************************************************************************************
     * */

    @Override
    public OwnPair put(String key, Object value) {
        super.protected_putOne(key, value);
        return this;
    }

    @Override
    public OwnPair putIfAbsent(String sourceKey, Object backupValue) {
        super.protected_putIfAbsent(sourceKey, backupValue);
        return this;
    }

    @Override
    public OwnPair putAll(Map map) {
        if(map == null || map.isEmpty()) return this;
        for (Object o : map.entrySet()) {
            Map.Entry e = (Map.Entry) o;
            super.protected_putOne(ObjKit.asStringValue(e.getKey(), null), e.getValue());
        }
        return this;
    }

    @Override
    public OwnPair putAll(OwnPairs pairs) {
        if(pairs != null && !pairs.isEmpty()) {
            for (Object o : pairs.entrySet()) {
                Map.Entry e = (Map.Entry) o;
                super.protected_putOne(ObjKit.asStringValue(e.getKey(), null), e.getValue());
            }
        }
        return this;
    }

    public OwnPair putAll(Object bean) {
        if(bean == null) return this;
        Map<String, Object> valuesMap = ObjKit.allFieldValue(bean);
        for (Map.Entry<String, Object> e : valuesMap.entrySet()) {
            super.protected_putOne(e.getKey(), e.getValue());
        }
        return this;
    }

    public OwnPair putAll(String jsonObject) {
        if(!VerifyKit.isJsonObject(jsonObject)) return this;
        JsonNode jsonNode = JsonKit.readToNode(jsonObject);
        Iterator<Map.Entry<String, JsonNode>> fields = jsonNode.fields();
        while (fields.hasNext()) {
            Map.Entry<String, JsonNode> e = fields.next();
            String value = e.getValue().toString();
            super.protected_putOne(e.getKey(), ObjKit.stringToRealValue(ObjKit.asStringValue(value, null), true));
        }
        return this;
    }

    @Override
    public OwnPair remove(Object key) {
        super.protected_removeOne(key);
        return this;
    }

    @Override
    public OwnPair removeAll(Object... keys) {
        super.protected_removeAll(keys);
        return this;
    }

    @Override
    public OwnPair removeAll(Collection<?> keys) {
        super.protected_removeAll(keys);
        return this;
    }

    @Override
    public OwnPair removeAll(OwnRows<?> keys) {
        super.protected_removeAll(keys);
        return this;
    }

    @Override
    public OwnPair removeAll(Iterable<?> keys) {
        super.protected_removeAll(keys);
        return this;
    }

    @Override
    public OwnPair remove(String key, Object value) {
        super.protected_removeOne(key, value);
        return this;
    }

    @Override
    public OwnPair removeAll(Map<? extends String, ?> map) {
        super.protected_removeAll(map);
        return this;
    }

    @Override
    public OwnPair removeAll(OwnPairs<? extends String, ?> pair) {
        super.protected_removeAll(pair);
        return this;
    }

    public OwnPair removeAll(String jsonObject) {
        if(!VerifyKit.isJsonObject(jsonObject)) return this;
        JsonNode jsonNode = JsonKit.readToNode(jsonObject);
        if(jsonNode.isEmpty()) return this;
        Iterator<Map.Entry<String, JsonNode>> fields = jsonNode.fields();
        while (fields.hasNext()) {
            Map.Entry<String, JsonNode> e = fields.next();
            super.protected_removeOne(e.getKey(), ObjKit.stringToRealValue(ObjKit.asStringValue(e.getValue(), null), true));
        }
        return this;
    }


    public OwnPair removeAll(Object javaBean) {
        if(javaBean == null) return this;
        Map<String, Object> fieldMap = ObjKit.allFieldValue(javaBean.getClass());
        return this.removeAll(fieldMap);
    }

    @Override
    public OwnPair replace(String key, Object newValue) {
        super.protected_replace(key, newValue);
        return this;
    }

    @Override
    public OwnPair replace(String key, Object oldValue, Object newValue) {
        super.protected_replace(key, oldValue, newValue);
        return this;
    }

    public <T>T get(String key, Class<T> valueType) {
        return (T) super.get(key);
    }

    public <T>T get(String key, C<T> valueType) {
        return (T) ObjKit.toRealValue(super.get(key), valueType);
    }

    @Override
    public boolean containsAllKey(String... keys) {
        return super.containsAllKey(keys);
    }

    @Override
    public boolean containsAnyKey(String... keys) {
        return super.containsAnyKey(keys);
    }

    @Override
    public boolean containsAllValue(Object... values) {
        return super.containsAllValue(values);
    }

    @Override
    public boolean containsAnyValue(Object... values) {
        return super.containsAllValue(values);
    }
}
